package com.bw.common.databus;

import androidx.annotation.NonNull;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;

/**
 * 基于美团方案修改livedata lastverion值保证有观察者订阅到mutablelivedata时lastvertion值为初始状态-1，
 * 防止数据倒灌发生
 * */
public class LiveDataBus<T> extends MutableLiveData<T> {
    //重写订阅方法->保证lastversion值为-1
    @Override
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        super.observe(owner, observer);
        try {
            hookLastVertion(observer);
        } catch (NoSuchFieldException | IllegalAccessException
                | NoSuchMethodException | InvocationTargetException e) {
            e.printStackTrace();
        }
    }
    private void hookLastVertion(Observer<? super T> observer) throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        //获取livedata类型
        Class<LiveData>liveDataClass = LiveData.class;
        //反射获取livedata class下的observer属性
        Field fieldmObserver = liveDataClass.getDeclaredField("mObservers");
        //破坏mObservers私有型
        fieldmObserver.setAccessible(true);
        //获取mObservers值
        Object mObservers = fieldmObserver.get(this);
        //获取mObservers类型
        Class<?>mObserversClass = mObservers.getClass();
        //获取mObserversClass get方法
        Method methodGet = mObserversClass.getDeclaredMethod("get",Object.class);
        methodGet.setAccessible(true);
        //执行get方法获取返回值
        Object entity = methodGet.invoke(mObservers,observer);
        //获取返回值
        Object observerWrapper = ((Map.Entry)entity).getValue();
        //获取基类中的lastvertion
        Field mLastVertion = mObserversClass.getDeclaredField("mLastVertion");
        mLastVertion.setAccessible(true);
        //获取LiveData下的vertion
        Field mVertion = liveDataClass.getDeclaredField("mVersion");
        mVertion.setAccessible(true);
        Object mVersionObject = mVertion.get(this);
        //改变lastvertion值
        mLastVertion.set(observerWrapper,mVersionObject);
    }

}
